package xdu.lz.stage6_threadpool.chapter1_threadPoolExecutor;

import java.util.concurrent.*;

/**
 * Created at 2019/10/23 0023 上午 11:05
 * interface:     Executor
 * subInterface:   ->ExecutorService
 * subAbsClass        -> abstractExecutorService
 * subClass              ->ThreadPoolExecutor
 *
 * 线程池七大参数，重要。问过
 *
 * 主要是用来创建自定义线程池，但是一般推荐用Excutors的创建工具来创建。
 */
public class CustomerThreadPool {


    /**
     * Creates a new {@code ThreadPoolExecutor} with the given initial
     * parameters.
     * <p>
     * corePoolSize: the number of threads to keep in the pool, even
     * if they are idle, unless {@code allowCoreThreadTimeOut} is set
     * <p>
     * maximumPoolSize: the maximum number of threads to allow in thepool
     * <p>
     * keepAliveTime:when the number of threads is greater than
     * the core, this is the maximum time that excess idle threads
     * will wait for new tasks before terminating.
     * <p>
     * unit: the time unit for the {@code keepAliveTime} argument
     * <p>
     * workQueue: the queue to use for holding tasks before they are
     * executed.  This queue will hold only the {@code Runnable}
     * tasks submitted by the {@code execute} method.
     * <p>
     * threadFactory :the factory to use when the executor creates a new thread
     * public interface ThreadFactory {
     * Thread newThread(Runnable r);
     * }
     * <p>
     * handler:the handler to use when execution is blocked
     * because the thread bounds and queue capacities are reached
     * {@link RejectedExecutionHandlerImpl}
     *
     * @throws IllegalArgumentException if one of the following holds:<br>
     *                                  {@code corePoolSize < 0}<br>
     *                                  {@code keepAliveTime < 0}<br>
     *                                  {@code maximumPoolSize <= 0}<br>
     *                                  {@code maximumPoolSize < corePoolSize}
     * @throws NullPointerException     if {@code workQueue}
     *                                  or {@code threadFactory} or {@code handler} is null
     */
    private static ThreadPoolExecutor buildThread() {
        ThreadPoolExecutor executor =
                new ThreadPoolExecutor(1, 2, 200, TimeUnit.SECONDS,
                        new ArrayBlockingQueue<>(1),
                        new ThreadFactory() {
                            @Override
                            public Thread newThread(Runnable r) {
                                return new Thread(r);
                            }
                        },
                        new ThreadPoolExecutor.AbortPolicy());
        executor.submit(()->doWork(5));
        executor.submit(()->doWork(10));
        executor.submit(()->doWork(5));
        executor.submit(()->doWork(5));
        return executor;
    }


    private static void doWork(long seconds) {
        System.out.println(Thread.currentThread().getName() + " work");
        try {
            Thread.sleep(seconds*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " finished");
    }

    public static void main(String[] args) throws InterruptedException {

        ThreadPoolExecutor threadPoolExecutor = buildThread();

        int keepAliveCount = -1;
        int queueSize = -1;
        boolean flag = true;
        while (flag) {
            if(keepAliveCount != threadPoolExecutor.getActiveCount()
                    || queueSize != threadPoolExecutor.getQueue().size()){
                System.out.println("keepAliveCount = " + threadPoolExecutor.getActiveCount());
                System.out.println("queueSize = " + threadPoolExecutor.getQueue().size());
                System.out.println("maxSize = " + threadPoolExecutor.getMaximumPoolSize());
                System.out.println("coreSize = " + threadPoolExecutor.getCorePoolSize());
                keepAliveCount = threadPoolExecutor.getActiveCount();
                queueSize = threadPoolExecutor.getQueue().size();
                System.out.println("================================");

            }
        }

    }
}
